package tech.aistar.design.singleton.version03;

/**
 * 本类用来演示: 懒汉模式(延迟加载) - 多线程安全
 *
 * @author: success
 * @date: 2021/3/17 10:31 上午
 */
public class Single03Demo {

    //2. 提供本类的唯一实例
    private static Single03Demo instance = null;

    //1. 私有化构造
    private Single03Demo(){
        System.out.println("Single03Demo...");
    }

    //3. 提供一个公开的方法来返回这个类的唯一实例

    //为什么在多线程环境下是不安全的
    //a. 比如A,B俩个线程同时执行getInstance方法 - 同时进入该方法体
    //b. 有可能instance == null,A和B俩线程同时进行判断,同时为true
    //c. 同时进入到if块中去new Single02Demo();

    //如何解决? - 使用java中的关键字synchronized - 申请一个"锁"对象
    //当A线程执行getInstance方法的时候,就会去申请一个"锁"
    //目的 - 哪个线程先抢到这个"锁",那么就由哪个线程进到方法体中去执行
    //      其余的线程就会在等待队列上排队候着.

    //当得到"锁"资源的A线程执行完毕之后,会释放"锁"资源,然后所有的线程[包括A]继续
    //争抢这个"锁",谁抢到谁进去.

    //缺点 - 因为多个线程会频繁调用getInstance方法,频繁去申请和创建"锁"对象
    //但是"锁"也是属于比较昂贵的资源,导致运行效率变低.
    public static synchronized Single03Demo getInstance(){
        if(instance == null){
            instance = new Single03Demo();
        }
        return instance;
    }
}

class TestSingle02Demo{
    public static void main(String[] args) {
        Single03Demo s1 = Single03Demo.getInstance();
        Single03Demo s2 = Single03Demo.getInstance();
        System.out.println(s1 == s2);//true
    }
}